// 导出页面为PDF格式
let html2Canvas = require('./html2canvas/html2canvas')
import JsPDF from 'jspdf'

export default{
  install (Vue, options) {
    /*
      dom:要导出的dom元素，支持domId,和默认padDom的Id导出
    */
    Vue.prototype.exportDomPdf = function (dom, options)  {
      let ths = this;
      let exportDom;
      const key = Math.round(Math.random() * 1000000);
      const pdfTitle = options.title || 'pdf文档';
      this.$message({
        showClose: true,
        message: '正在导出' + pdfTitle + ',请稍后...'
      });
      if(!dom || typeof (dom) === 'string'){
        exportDom = document.querySelector('#'+ dom || '#pdfDom');
      }else{
        exportDom = dom;
      }
      return html2Canvas(exportDom, { allowTaint: true, useCORS: true }).then(function (canvas) {
        try {
          let contentWidth = canvas.width
          let contentHeight = canvas.height
          let pageHeight = contentWidth / 592.28 * 841.89
          let leftHeight = contentHeight
          let position = 0
          let imgWidth = 595.28
          let imgHeight = 592.28 / contentWidth * contentHeight
          let pageData = canvas.toDataURL('image/jpeg', 1.0)
          let PDF = new JsPDF('', 'pt', 'a4')
          if (leftHeight < pageHeight) {
            PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
          } else {
            while (leftHeight > 0) {
              PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
              leftHeight -= pageHeight
              position -= 841.89
              if (leftHeight > 0) {
                PDF.addPage()
              }
            }
          }
          PDF.save(pdfTitle + '.pdf')
        } catch (e) {
          console.log('exportDomPdf error:', e);
        }
        this.$message({
          showClose: true,
          message: '导出成功',
          type: 'success'
        });
        return true;
      });
    },

    /**
     * 多个DOM节点导出成pdf文件
     * 除非特殊情况，强烈建议domArr里只有一个dom节点，即length为1;length越大，导出越慢
     * domArr里面的每个DOM节点宽度建议给一个固定的值，避免页面缩放/电脑分辨率等问题造成打印出的文件不一样
     * 默认A4纸格式（A4纸宽210，高297。打印内容上下左右均留下30的空白，那么内容的宽度大约为150，高度大约为240）
     * @param { Array<DOM> | NodeList } domArr DOM数组（可以是通过querySelectorAll获取的NodeList）
     * @param { Object } options 配置信息
     * @param { String } options.title 导出的pdf文件名（不要带 .pdf）
     * @param { Number } options.top 导出文件的上边距，默认 30
     * @param { Number } options.left 导出文件的左边距，默认 30
     * @param { Number } options.bottom 导出文件的底部边距，默认 30
     * @param { Number } options.width 导出文件的宽度，默认 150
     * @param { Number } options.height 导出文件的高度，默认 240
     */
    Vue.prototype.exportMultiDomToPdf = function(domArr, options = {}) {
      function getValue(v, defaultValue) {
        if (typeof v === 'number') {
          return v
        }
        if (v === undefined) {
          return defaultValue
        }
        throw new Error('参数应当是Number类型')
      }

      const a4Format = {
        top: getValue(options.top, 30),
        bottom: getValue(options.bottom, 30),
        left: getValue(options.left, 30),
        width: getValue(options.width, 150),
        height: getValue(options.height, 240)
      };

      if (a4Format.left + a4Format.width > 210) {
        console.error('打印内容宽度超过页面的宽度！')
      }

      if (a4Format.top + a4Format.height + a4Format.bottom > 300) {
        console.error('打印内容高度超过页面的高度！')
      }

      /**
       * 把一个大的canvas截成几部分，用于处理换页
       * @param  { canvas } canvas 大的canvas图像对象
       * @param { Number } cutHeight 初始截取的高度
       */
      function getSplitCanvas(canvas, cutHeight) {
        const ratio = canvas.width / a4Format.width;
        cutHeight = cutHeight * ratio;

        let remainHeight = canvas.height; // 截取之后，页面还剩余多少高度
        let currentHeight = 0; // 截取到canvas的高度位置
        let resultArr = [];
        while(remainHeight > 0) {
          const tempCanvas = document.createElement('canvas');
          const tempCtx = tempCanvas.getContext('2d');
          tempCanvas.width = canvas.width;
          tempCanvas.height = cutHeight;
          tempCtx.drawImage(canvas, 0, currentHeight, canvas.width, cutHeight, 0, 0, canvas.width, cutHeight);

          resultArr.push({
            canvas: tempCanvas,
            height: cutHeight / ratio
          });

          currentHeight += cutHeight;
          remainHeight -= cutHeight;

          cutHeight = Math.min((canvas.height - currentHeight), (a4Format.height * ratio));
        }
        return resultArr;
      }

      // 按照数组的顺序生成图片信息
      function generateCanvas (arr, resultArr) {
        if (arr.length === 0) {
          return new Promise(resolve => {
            resolve(resultArr)
          })
        }

        return html2Canvas(arr[0]).then(canvas => {
          const { scrollWidth: width, scrollHeight: height } = arr[0];

          // 宽度占满a4纸，计算缩放比例
          const ratio = width / a4Format.width;

          // 计算出在a4纸上的高度
          let finalHeight = height / ratio;
          finalHeight = Number(finalHeight.toFixed(1));
          resultArr.push({
            height: finalHeight,
            canvas
          });
          arr.splice(0, 1);
          return generateCanvas(arr, resultArr)
        })
      }

      const key = Math.random() * 10000;
      const pdfTitle = options.title || 'pdf文档'
      this.$message({
        showClose: true,
        message: '正在导出' + pdfTitle + ',请稍后...'
      });

      // 通过querySelector得到是NodeList，并不是数组
      const elementArr = [];
      for(let i = 0, length = domArr.length; i < length; i++) {
        let dom = domArr[i];
        elementArr.push(dom);
      }

      generateCanvas(elementArr, []).then(canvasArr => {
        const heightArr = canvasArr.map(item => item.height);
        let arr = [];
        let remainHeight = a4Format.height; // 页面剩余空间的高度
        for(let i = 0, length = heightArr.length; i < length; i++) {
          const height = heightArr[i];
          if (height >= remainHeight + a4Format.bottom) { // 高度太大，超出当前页。切割图片
            const tempArr = getSplitCanvas(canvasArr[i].canvas, remainHeight);
            arr = arr.concat(tempArr);
          } else if (height > remainHeight && height <= remainHeight + a4Format.bottom) { // 当前页面内容占满。换下一页
            arr.push(canvasArr[i]);
            remainHeight = a4Format.height;
          } else if (height < remainHeight) { // 当前页面还有空间，重新计算页面剩余空间的高度
            arr.push(canvasArr[i]);
            remainHeight -= height;
          }
        }

        let pdf = new JsPDF();
        let currentTop = a4Format.top;
        let maxHeight = a4Format.height;
        for(let i = 0, length = arr.length; i < length; i++) {
          const { canvas, height } = arr[i];
          if (height + currentTop > maxHeight + a4Format.bottom) { // 如果超出一页的高度，那么新增一页
            pdf.addPage('a4');
            currentTop = a4Format.top;
          }
          pdf.addImage(canvas.toDataURL('image/jpeg'), 'JPEG', a4Format.left, currentTop, a4Format.width, height);
          // pdf.addImage(canvas.toDataURL(), 'PNG', a4Format.left, currentTop, a4Format.width, height);
          currentTop += height;
        }
        pdf.save(`${pdfTitle}.pdf`)
        this.$message({
          showClose: true,
          message: '导出成功',
          type: 'success'
        });
      })
    }
  }
}
